#ifndef APP_H
#define APP_H
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include "AppView.hpp"
#include "AppView.hpp"
#include "AppModel.hpp"
#include "AppPreferences.hpp"
#include "AppAction.hpp"

/**
 * Container for an application :
 * contains the view, model, preferences and associated actions
 */
class App {
public:
  /**
   * Creates an empty application
   */
  App();

  /**
   * Create a full specified application
   * @param view specify the associated view
   * @param model specify the associated model
   * @param pref specify the associated preferences
   * @param action specify the associated actions
   */
  App(AppView* view, AppModel* model, AppPreferences* pref, AppAction* action);

  /**
   * Setup an application
   * @param view specify the associated view
   * @param model specify the associated model
   * @param pref specify the associated preferences
   * @param action specify the associated actions
   */
  void setApp(AppView* view, AppModel* model, AppPreferences* pref,
      AppAction* action);

  /**
   * Get the view
   * @returns the view of this application
   */
  AppView* getView();

  /**
   * Get the model
   * @returns the model of this application
   */
  AppModel* getModel();

  /**
   * Get the preferences
   * @returns the preferences of this application
   */
  AppPreferences* getPreferences();

  /**
   * Get the actions
   * @returns the actions of this application
   */
  AppAction* getAction();

  /**
   * Destroy the app container but not the content of contained specification
   */
  virtual ~App();

private:
  friend class boost::serialization::access;
  template<class Archive>
  /**
   * Saves the preference or load preferences to / from an archive
   */
  void serialize(Archive & ar, const unsigned int version) {
    ar & _model;
    ar & _pref;
  }

 protected:
  AppView* _view;
  AppModel* _model;
  AppPreferences* _pref;
  AppAction* _action;
};

typedef App* create_appl();
typedef void destroy_appl(App*);


#endif
